


IF ~DEFINED _UNSIGNED_INTEGER_H_
_UNSIGNED_INTEGER_H_	EQU	1

UnsignedInteger.MAX	EQU	0FFFFFFFFh

; bool UnsignedInteger::parseStringANSI(char* str, UINT8 radix, unsigned *output);
UnsignedInteger.parseStringANSI:
	push	ebx
	push	esi
; stack: |esi |ebx |ret |str |radix|outp|
	xor	eax,	eax
	xor	ebx,	ebx
	
	mov	esi,	[esp+3*4]
	test	esi,	esi
	; TODO: NullPointerException
	jz	.false
	cmp	DWORD [esp+5*4], 0
	; TODO: NullPointerException
	je	.false
	
	cmp	BYTE [esi],	0
	; TODO: NumberFormatException
	je	.false
	;mov	ecx,	[esp+4*4]	; force DWORD align
	movzx	ecx,	BYTE [esp+4*4]	; ecx = radix
	cmp	cl,	2
	; TODO: InvalidArgumentException
	jb	.false
	cmp	cl,	36
	jna	.loop0
.false:
	xor	eax,	eax
	jmp	.return
.loop0:
	mov	bl,	[esi]
	test	bl,	bl
	jz	.true
	inc	esi
	sub	bl,	'0'
	; TODO: NumberFormatException
	jb	.false
	cmp	bl,	9
	jna	@F
	sub	bl,	'A'-'0'-10
	; TODO: NumberFormatException
	jb	.false
	cmp	bl,	36
	jna	@F
	sub	bl,	'a'-'A'
	; TODO: NumberFormatException
	jb	.false
@@:	cmp	bl,	cl
	; >= radix, NumberFormatException
	jae	.false
	mul	ecx
	; out of range, NumberFormatException
	jc	.false
	add	eax,	ebx
	jmp	.loop0
.true:
	mov	ecx,	[esp+5*4]
	mov	[ecx],	eax
	mov	eax,	1
.return:
	pop	esi
	pop	ebx
	retn	3*4

; bool UnsignedInteger::toStringANSI(char *buffer, int i, unsigned radix);
UnsignedInteger.toStringANSI:
	push	ebx
	push	edi
	push	ebp
	mov	ebp,	esp
; stack: |ebp |edi |ebx |ret |buffer|i   |radix|
LABEL	.buffer	AT	ebp+4*4
LABEL	.i	AT	ebp+5*4
LABEL	.radix	AT	ebp+6*4
	mov	edi,	[.buffer]
	test	edi,	edi
	; TODO: NullPointerException
	jz	.false
	movzx	ecx,	BYTE [.radix]
	cmp	ecx,	2
	; TODO: InvalidArgumentException
	jb	.false
	cmp	ecx,	36
	jna	@F
.false:
	xor	eax,	eax
	jmp	.return
@@:	mov	eax,	[.i]
	test	eax,	eax		; cmp eax, 0
	jnz	@F
	mov	WORD [edi],	'0'
	jmp	.true
@@:	sub	esp,	32		; reserve space
	mov	ebx,	esp
.loop1:
	xor	edx,	edx
	div	ecx
	add	dl,	'0'
	cmp	dl,	'9'
	jna	@F
	add	dl,	'A'-'9'-1
@@:	mov	[ebx],	dl
	inc	ebx
	test	eax,	eax
	jnz	.loop1
@@:	dec	ebx			; loop to reverse
	mov	al,	[ebx]
	stosb
	cmp	ebx,	esp
	jne	@B
	mov	BYTE [edi],	0
.true:
	mov	eax,	1
.return:
	mov	esp,	ebp
	pop	ebp
	pop	edi
	pop	ebx
	retn	3*4

; void UnsignedInteger::_toHexString(char* buffer, unsigned i);
UnsignedInteger._toHexString:
	mov	edx,	[esp+4]	; buffer
	test	edx,	edx
	jz	.return
	mov	BYTE [edx+8],	0
	
	mov	ecx,	3
.loop0:
	mov	al,	[esp+ecx+2*4]
	mov	ah,	al
	shr	al,	4
	and	ah,	0Fh
	or	ax,	'00'
	cmp	al,	'9'
	jna	@F
	add	al,	'A'-'9'-1
@@:	cmp	ah,	'9'
	jna	@F
	add	ah,	'A'-'9'-1
@@:	mov	[edx],	ax
	test	ecx,	ecx
	jz	.return
	add	edx,	2
	dec	ecx
	jmp	.loop0
.return:
	retn	2*4

END IF ; ~DEFINED _UNSIGNED_INTEGER_H_
